package basics;

abstract public class ConversaoDeBases {

	static public String DecToBin(long num, int size) {

		String result;

		// Converte o número para uma string que é a sua representação em
		// binário
		if (num < 0)
			num = num + (long) Math.pow(2, size); // complemento de 2.

		result = Long.toBinaryString(num);
		result = normalizeNumericString(result, size);

		return result;
	}

	static public String DecToBin(long num) {

		return DecToBin(num, 32);
	}

	static public String DecToBin(String num, int size) {

		long numero = Long.valueOf(num);

		return DecToBin(numero, size);
	}

	static public String DecToBin(String num) {

		return DecToBin(num, 32);
	}

	static public String normalizeNumericString(String numericString, int size) {
		String normalizedNumericString = numericString;

		while (normalizedNumericString.length() < size)
			normalizedNumericString = "0".concat(normalizedNumericString);

		return normalizedNumericString;
	}

	static public long binToDecUnsigned(String bin) {
		int i;
		long value = 0;
		int maxPower = bin.length() - 1;

		for (i = maxPower; i >= 0; i--) {

			if (bin.charAt(i) == '1') {
				value += Math.pow(2, maxPower - i);
			}
		}
		return value;
	}

	static public long binToDecSigned(String bin) {
		int i;
		long value = 0;
		int maxPower = bin.length() - 1;
		boolean negativo = false;

		// Se é negativo
		if (bin.charAt(0) == '1')
			negativo = true;

		for (i = maxPower; i >= 0; i--) {

			if (((!negativo) && bin.charAt(i) == '1')
					|| (negativo && (bin.charAt(i) == '0'))) {
				value += Math.pow(2, maxPower - i);
			}
		}

		return negativo ? -(value + 1) : value;
	}

	static public String decToHex(long num) {
		return binToHex(DecToBin(num), 8);
	}

	static public String decToHex(long num, int size) {
		return binToHex(DecToBin(num), size);
	}

	static public String binToHex(String num) {
		return binToHex(num, 8);
	}

	static public String binToHex(String num, int size) {

		String result = "";
		int val = 0;

		for (int i = 0; i < (size * 4); i = i + 4) {

			if (num.charAt(i) == '1')

				val += 8;

			if (num.charAt(i + 1) == '1')

				val += 4;

			if (num.charAt(i + 2) == '1')

				val += 2;

			if (num.charAt(i + 3) == '1')

				val += 1;

			switch (val) {
			case 0:
				result += "0";

				break;

			case 1:

				result += "1";

				break;

			case 2:

				result += "2";

				break;

			case 3:

				result += "3";

				break;

			case 4:

				result += "4";

				break;

			case 5:

				result += "5";

				break;

			case 6:

				result += "6";

				break;

			case 7:

				result += "7";

				break;

			case 8:

				result += "8";

				break;

			case 9:

				result += "9";

				break;

			case 10:

				result += "A";

				break;

			case 11:

				result += "B";

				break;

			case 12:

				result += "C";

				break;

			case 13:

				result += "D";

				break;

			case 14:

				result += "E";

				break;

			case 15:

				result += "F";

				break;
			}

			val = 0;
		}

		return "0x" + normalizeNumericString(result, size);

	}

	static public String hexToBin(String num, int size) {

		String result = "";

		for (int i = 2; i < num.length(); i++) {

			switch (num.charAt(i)) {

			case '1':

				result += "0001";

				break;

			case '2':

				result += "0010";

				break;

			case '3':

				result += "0011";

				break;

			case '4':

				result += "0100";

				break;

			case '5':

				result += "0101";

				break;

			case '6':

				result += "0110";

				break;

			case '7':

				result += "0111";

				break;

			case '8':

				result += "1000";

				break;

			case '9':

				result += "1001";

				break;

			case 'A':

				result += "1010";

				break;

			case 'B':

				result += "1011";

				break;

			case 'C':

				result += "1100";

				break;

			case 'D':

				result += "1101";

				break;

			case 'E':

				result += "1110";

				break;

			case 'F':

				result += "1111";

				break;
			}
		}

		return normalizeNumericString(result, size);

	}

	static public String hexToBin(String num) {
		return hexToBin(num, 32);
	}

}
